মিউটেক্স (Mutex) হলো C++ এর একটি সিঙ্ক্রোনাইজেশন প্রক্রিয়া, যা একাধিক থ্রেডকে সমন্বিতভাবে ডেটা ব্যবহারের সুযোগ দেয়, কিন্তু এক থ্রেড অন্য থ্রেডের কাজ শেষ না হওয়া পর্যন্ত সেই ডেটা অ্যাক্সেস করতে পারে না। মিউটেক্স ব্যবহার করে একাধিক থ্রেডের মধ্যে ডেটা শেয়ার করার সময় ডেটার সামঞ্জস্যতা (consistency) বজায় রাখা যায় এবং ডেটা রেস সমস্যা প্রতিরোধ করা যায়।
সিঙ্ক্রোনাইজেশন একটি প্রক্রিয়া, যা নিশ্চিত করে যে একাধিক থ্রেড একসঙ্গে একই ডেটা অ্যাক্সেস বা মডিফাই করতে পারবে না। যদি সিঙ্ক্রোনাইজেশন না করা হয়, তবে ডেটা রেস নামক সমস্যা হতে পারে, যেখানে একাধিক থ্রেড একসঙ্গে একই ডেটা মডিফাই করতে গেলে ভুল বা অনির্দেশ্য আউটপুট আসতে পারে।
সিঙ্ক্রোনাইজেশন ব্যবহারের প্রয়োজনীয়তা:
C++ এ mutex
লাইব্রেরি থেকে মিউটেক্স ব্যবহৃত হয়। এটি সাধারণত তিনটি মেথড দ্বারা কাজ করে:
true
রিটার্ন করে, ব্যর্থ হলে false
রিটার্ন করে।#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx; // মিউটেক্স তৈরি করা
void printMessage(const string& msg) {
mtx.lock(); // মিউটেক্স লক করা
cout << msg << endl;
mtx.unlock(); // মিউটেক্স আনলক করা
}
int main() {
thread t1(printMessage, "Hello from thread 1");
thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
বর্ণনা:
mtx.lock()
এবং mtx.unlock()
ব্যবহার করে মিউটেক্স লক এবং আনলক করা হয়েছে, যাতে cout
স্টেটমেন্ট একসঙ্গে একাধিক থ্রেড দ্বারা অ্যাক্সেস না হয়।লকার ব্যবহার করে মিউটেক্সের লক এবং আনলক করা আরও সহজ করা যায়। lock_guard
একটি সিঙ্ক্রোনাইজেশন ক্লাস, যা মিউটেক্স লক করে এবং যখন স্কোপের বাইরে চলে যায়, তখন স্বয়ংক্রিয়ভাবে আনলক করে।
lock_guard
ব্যবহার#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx;
void printMessage(const string& msg) {
lock_guard<mutex> lock(mtx); // lock_guard ব্যবহার করে মিউটেক্স লক
cout << msg << endl;
}
int main() {
thread t1(printMessage, "Hello from thread 1");
thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
বর্ণনা:
lock_guard
ব্যবহার করে মিউটেক্স লক করা হয়েছে, এবং কাজ শেষে এটি স্বয়ংক্রিয়ভাবে আনলক হয়।unlock()
কল করার দরকার নেই, যা কোডকে আরও সুরক্ষিত এবং পরিষ্কার করে তোলে।ডেডলক হলো এমন একটি অবস্থা যেখানে দুটি বা ততোধিক থ্রেড একে অপরের উপর নির্ভরশীল হয়ে অপেক্ষা করে, ফলে তারা কোন কাজই করতে পারে না। সাধারণত মিউটেক্স ব্যবহারের সময় ডেডলক সমস্যা দেখা দিতে পারে।
ডেডলক প্রতিরোধের জন্য কিছু পদ্ধতি:
try_lock()
ব্যবহার করে ডেডলক প্রতিরোধ করা যায়, কারণ এটি ব্যর্থ হলে false
রিটার্ন করে, ফলে থ্রেডটি অবিরত অপেক্ষা করে না।lock_guard
বা unique_lock
ব্যবহার করে লক করার প্রক্রিয়া সহজ করা যায় এবং স্কোপের বাইরে যাওয়ার সময় এটি স্বয়ংক্রিয়ভাবে আনলক হয়।#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx1, mtx2;
void thread1() {
if (mtx1.try_lock()) {
this_thread::sleep_for(chrono::milliseconds(100)); // সামান্য বিরতি
if (mtx2.try_lock()) {
cout << "Thread 1 is running." << endl;
mtx2.unlock();
}
mtx1.unlock();
}
}
void thread2() {
if (mtx2.try_lock()) {
this_thread::sleep_for(chrono::milliseconds(100)); // সামান্য বিরতি
if (mtx1.try_lock()) {
cout << "Thread 2 is running." << endl;
mtx1.unlock();
}
mtx2.unlock();
}
}
int main() {
thread t1(thread1);
thread t2(thread2);
t1.join();
t2.join();
return 0;
}
বর্ণনা:
try_lock()
ব্যবহার করে থ্রেডে ডেডলক প্রতিরোধ করা হয়েছে।try_lock()
এর মাধ্যমে লক করতে ব্যর্থ হয়, তবে সেটি অবিরত অপেক্ষা না করে ফিরে আসে এবং পরবর্তী কাজ করতে পারে।lock_guard
ও try_lock()
ব্যবহার করে ডেডলক সমস্যার সমাধান করা যায়।মিউটেক্স এবং সিঙ্ক্রোনাইজেশন ব্যবহার করে প্রোগ্রামে ডেটা শেয়ারিং আরও নিরাপদ এবং নির্ভরযোগ্য করা যায়, যা বড় মাল্টিথ্রেডেড প্রোগ্রাম তৈরিতে অত্যন্ত গুরুত্বপূর্ণ।
common.read_more